/**
 * 
 */
package kit4j.ui.cs.swing.dnd;

import java.awt.Component;
import java.awt.Container;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;

import javax.swing.TransferHandler.TransferSupport;

/**
 * @author MiniKnife
 * 
 */
public abstract class AbstractComponentDropper {
	
//	private static final Logger log = LoggerFactory.getLogger(AbstractComponentDropper.class);

	protected Container container;

	public AbstractComponentDropper(Container container) {
		this.container = container;
	}

	/**
	 * 执行Component对象被放置要进行的操作。
	 * 
	 * @param support
	 * @return 如果Component对象被成功放置，则返回true，否则返回false。
	 */
	public boolean dropComponent(TransferSupport support) {
		Transferable tf = support.getTransferable();
		Container container = this.container;

		if (container == null) {
			container = (Container) support.getComponent();
		}

		try {
			Component comp = (Component) tf.getTransferData(new DataFlavor(
					DataFlavor.javaJVMLocalObjectMimeType + ";class="
							+ Component.class.getCanonicalName()));
			Container oldContainer = comp.getParent();

			// 添加组件到指定容器并刷新容器界面
			if (addComponent(container, comp, support)) {
				validateAndRepaintContainer(container);

				// 从原容器中移除组件并刷新原容器界面
				if (oldContainer != null && oldContainer != container) {
					oldContainer.remove(comp);
					validateAndRepaintContainer(oldContainer);
				}
			}

			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 验证并重绘指定的容器。如果指定的容器存在父容器，则直接验证并重绘父容器。
	 * 
	 * @param container
	 *            要执行操作的容器
	 */
	protected void validateAndRepaintContainer(Container container) {
		Container parent = container.getParent();

		if (parent != null) {
			parent.validate();
			parent.repaint();
		} else {
			container.validate();
			container.repaint();
		}
	}

	/**
	 * 向指定的容器中添加指定的Component对象组件。
	 * 
	 * @param container
	 *            容器
	 * @param comp
	 *            要添加的组件
	 * @param support
	 *            包含拖放传输详细信息的TransferSupport对象
	 * @return 如果组件成功添加到容器中，返回true，否则返回false。
	 */
	abstract protected boolean addComponent(Container container,
			Component comp, TransferSupport support);
}
